<?php
/*

  $Id: SAPARCELPLUS.php,v 0.1 2003/04/15 Charles Oertel

  Catalog Side / Includes / Modules / Shipping
  osCommerce, Open Source E-Commerce Solutions
  http://www.oscommerce.com

  Copyright (c) 2003 Charles Oertel for FineBushPeople.net

  Released under the GNU General Public License

  USAGE
  This module calculates shipping for small parcels according to the South
  African postal rates for domestic parcels.

  The postage is calculated at a fixed rate for every kg of weight of
  the parcel, with a flat fee for the first kilogram.

  Return values are:
  - Country = ZA, parcel weight < maximum : a quote for parcelplus
    or econoparcel (if weight less than 1kg) domestic delivery
  - Country = ZA, parcel weight > maximum : a message showing basket
    weight, weight limit, and saying that the weight exceeds the weight
    limit for this shipping option.  The radio button to select this option
    does not appear.
  - Country not ZA : $quote = false.  The option does not even appear on the
    checkout page.

  ACTIVATION AND CONFIGURATION

  To activate the module: go to the Admin screen, click on Modules,
  then click on Shipping.  A list of all shipping modules should appear.
  Click on the green dot next to the one labeled 'SA Domestic Parcels'.
  A list of settings will appear to the right.  
  Click on the Edit button.

  PLEASE NOTE THAT YOU WILL LOSE YOUR CURRENT SHIPPING RATES AND OTHER
  SETTINGS IF YOU TURN OFF THIS SHIPPING METHOD.  Make sure you keep a
  backup of your shipping settings somewhere at all times.

  NOTE: All weight units are assumed to be grams.

  SETTINGS:
  - Maximum weight of Econoparcel (currently 1kg)
  - Postage Rate of Econoparcel (currently R12.60)
  - Insurance rate on Econoparcel (currently 2%).  Set this to 0 if you
    do not want to insure the parcel.  The rate is based on the value
    of the order ($order->info['total']). Enter the percentage charge
    on the value of the parcel (e.g. 2 = 2%)
  - Minimum insurance fee,
  - Maximum insured value allowed,
  - First Kilogram Postage Rate for ParcelPlus parcels (greater than 1kg)
  - Rate per kilo thereafter
  - Maximum weight allowed: currently parcelplus is limited to
    30kg (30000g).  You can set this limit here.  If the items in the basket
    exceed this weight, the postage option is disabled with a message that
    the basket weight exceeds the permissable weight for parcelplus (you
    edit this message in catalog/includes/languanges/english/
    saparcelplus.php).

  NOTES ON ADAPTING THIS MODULE TO OTHER CASES:
  - This module was crafted from the sasmallparcel.php module submitted
    by Charles Oertel (FineBushPeople.net)
  - If you change the country of origin, you need to change code that refers
    to South Africa (ZA) in this place in the quote:
      if ($dest_country == 'ZA') {
  - There are three behaviours you can elicit at the checkout page:
    i   :: the quote appears and can be selected,
    ii  :: the title for the shipping method appears, but there is an error
           message and the shipping method cannot be selected, or
    iii :: the shipping method does not appear at all.
    
    To get i, example code looks like this:
      $this->quotes = array(
        'id' => $this->code,
        'module' => MODULE_SHIPPING_SAPARCELPLUS_TEXT_TITLE,
        'methods' => array(
          array(
            'id' => $this->code,
            'title' => $surfacemail_shipping_method,
            'cost' => $surfacemail_shipping_cost),
          array(
            'id' => $this->code,
            'title' => $airmail_shipping_method,
            'cost' => $airmail_shipping_cost)));
    
    To get ii, example code looks like this:
      $this->quotes = array(
        'id' => $this->code,
        'module' => MODULE_SHIPPING_SAPARCELPLUS_TEXT_TITLE,
        'methods' => array(
          array('title' => $this->quotes['error'])));
      $this->quotes['error'] = $shipping_weight . ' ' . 
                               MODULE_SHIPPING_SAPARCELPLUS_TEXT_UNITS . ' ' . 
                               MODULE_SHIPPING_SAPARCELPLUS_EXCEEDED_WEIGHT . ' ' . 
                               MODULE_SHIPPING_SAPARCELPLUS_MAX_WEIGHT . ' ' . 
                               MODULE_SHIPPING_SAPARCELPLUS_TEXT_UNITS;

    To get iii, example code looks like this:
      return false;   //'Letter Post is not available for destinations in South Africa.';
*/

  class saparcelplus {
    var $code, $title, $description, $enabled;

// class constructor
    function saparcelplus() {
    /**************************************************************************
    *                             Constructor                                 *
    **************************************************************************/
      $this->code = 'saparcelplus';
      $this->title = MODULE_SHIPPING_SAPARCELPLUS_TEXT_TITLE;
      $this->description = MODULE_SHIPPING_SAPARCELPLUS_TEXT_DESCRIPTION;
      $this->sort_order = MODULE_SHIPPING_SAPARCELPLUS_SORT_ORDER;
      $this->icon = '';
      $this->tax_class = MODULE_SHIPPING_SAPARCELPLUS_TAX_CLASS;
      $this->enabled = ((MODULE_SHIPPING_SAPARCELPLUS_STATUS == 'True') ? true : false);

    }

// class methods
    function quote($method = '') {
    /**************************************************************************
    *                                Quote                                    *
    * Purpose: Calculate shipping costs and options during checkout           *
    * Input  : order - the order object
    *          shipping_weight - the total weight of the order
    * Output : quote populated with options when all correct,
    *          quote populated with an error message when weight limit exceeded
    *          quote = false when invalid country (not South Africa)
    * Created: Charles Oertel 16/04/2003 (charles@finebushpeople.net)
    **************************************************************************/
      global $order, $shipping_weight;
      $error = false;

      $dest_country = $order->delivery['country']['iso_code_2'];
      if ($dest_country != 'ZA') {
          return false;   // 'ParcelPlus is only available for destinations in South Africa.';
      }

      if ($shipping_weight > MODULE_SHIPPING_SAPARCELPLUS_MAX_WEIGHT) { 
        $this->quotes = array('id' => $this->code,
                              'module' => MODULE_SHIPPING_SAPARCELPLUS_TEXT_TITLE,
                              'methods' => array(array('title' => $this->quotes['error'])));
        $this->quotes['error'] = $shipping_weight . ' ' . 
                                 MODULE_SHIPPING_SAPARCELPLUS_TEXT_UNITS . ' ' . 
                                 MODULE_SHIPPING_SAPARCELPLUS_EXCEEDED_WEIGHT . ' ' . 
                                 MODULE_SHIPPING_SAPARCELPLUS_MAX_WEIGHT . ' ' . 
                                 MODULE_SHIPPING_SAPARCELPLUS_TEXT_UNITS;
        return $this->quotes;
      }

      if ($shipping_weight <= MODULE_SHIPPING_SAPARCELPLUS_ECONOPARCEL_MAX_WEIGHT) {
         // do Econoplus calculations because the parcel is small
         $method = 'ECONOPARCEL';
      } else {
         $method = 'PARCELPLUS';
      }
      $shipping_cost = 0;
      $shipping_method = '';
      $order_total = $order->info['total'];

      if (constant('MODULE_SHIPPING_SAPARCELPLUS_'.$method.'_INSURANCE_RATE') > 0) {
         if ($order_total > MODULE_SHIPPING_SAPARCELPLUS_INSURANCE_MAXIMUM) {
            $order_total = MODULE_SHIPPING_SAPARCELPLUS_INSURANCE_MAXIMUM;
            $shipping_method .= 'Only the first ' . MODULE_SHIPPING_SAPARCELPLUS_INSURANCE_MAXIMUM . ' of the parcel value will be insured.';
         }
         $shipping_cost =  $order_total
                           * constant('MODULE_SHIPPING_SAPARCELPLUS_'.$method.'_INSURANCE_RATE')
                           / 100; // percent
         if ($shipping_cost < MODULE_SHIPPING_SAPARCELPLUS_INSURANCE_MINIMUM) $shipping_cost = MODULE_SHIPPING_SAPARCELPLUS_INSURANCE_MINIMUM;
      }
      $shipping_cost += constant('MODULE_SHIPPING_SAPARCELPLUS_'.$method.'_BASE_RATE');
      $shipping_cost += constant('MODULE_SHIPPING_SAPARCELPLUS_'.$method.'_UNIT_RATE')
                        * ceil(($shipping_weight - MODULE_SHIPPING_SAPARCELPLUS_ECONOPARCEL_MAX_WEIGHT) / 1000 );
      $shipping_cost += MODULE_SHIPPING_SAPARCELPLUS_HANDLING_FEE;

      $shipping_method .= constant('MODULE_SHIPPING_SAPARCELPLUS_TEXT_'.$method.'_WAY') . ' ' . 
                          $shipping_weight . ' ' . 
                          MODULE_SHIPPING_SAPARCELPLUS_TEXT_UNITS . ' - ' .
                          MODULE_SHIPPING_SAPARCELPLUS_TEXT_DELIVERYTIME;
                                   
      $this->quotes = array(
        'id' => $this->code,
        'module' => MODULE_SHIPPING_SAPARCELPLUS_TEXT_TITLE,
        'methods' => array(
          array(
             # 'id' => $this->code,
            'id' => $method,
            'title' => $shipping_method,
            'cost' => $shipping_cost)));

      if ($this->tax_class > 0) {
        $this->quotes['tax'] = tep_get_tax_rate($this->tax_class, $order->delivery['country']['id'], $order->delivery['zone_id']);
      }

      if (tep_not_null($this->icon)) $this->quotes['icon'] = tep_image($this->icon, $this->title);
      if ($error == true) $this->quotes['error'] = MODULE_SHIPPING_SAPARCELPLUS_INVALID_ZONE;

      return $this->quotes;
    }

    function check() {
    /**************************************************************************
    *                                 Check                                   *
    **************************************************************************/
      if (!isset($this->_check)) {
        $check_query = tep_db_query("select configuration_value from " . TABLE_CONFIGURATION . " where configuration_key = 'MODULE_SHIPPING_SAPARCELPLUS_STATUS'");
        $this->_check = tep_db_num_rows($check_query);
      }
      return $this->_check;
    }

    function install() {
    /**************************************************************************
    *                               Install                                   *
    * Purpose: Creates the correct keys in the configuration table for 
    *          automatic presentation of variables etc.  Pay attention to
    *          the key names and ensure they are returned by the keys() method
    *          below.
    * Output : Table populated with the keys (constants) and set to default
    *          values for South African small parcel letter post rates.
    * Remarks: This is where you define, and initialise all your constants and
    *          administrator-defined variables.
    **************************************************************************/
      tep_db_query("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, set_function, date_added) VALUES ('Enable SA Domestic Parcel Post', 'MODULE_SHIPPING_SAPARCELPLUS_STATUS', 'True', 'Do you want to offer South African Domestic Parcel shipping?', '6', '0', 'tep_cfg_select_option(array(\'True\', \'False\'), ', now())");
      tep_db_query("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added) values ('Sort order of display.', 'MODULE_SHIPPING_SAPARCELPLUS_SORT_ORDER', '0', 'Sort order of display. Lowest is displayed first.', '6', '0', now())");
     tep_db_query("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, use_function, set_function, date_added) values ('Tax Class', 'MODULE_SHIPPING_SAPARCELPLUS_TAX_CLASS', '0', 'Use the following tax class on the shipping fee.', '6', '0', 'tep_get_tax_class_title', 'tep_cfg_pull_down_tax_classes(', now())");
      tep_db_query("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added) values ('Maximum weight allowed.', 'MODULE_SHIPPING_SAPARCELPLUS_MAX_WEIGHT', '30000', 'Maximum allowed domestic parcel weight in grams.', '6', '0', now())");
      tep_db_query("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added) values ('Maximum weight for ECONOPARCEL parcels.', 'MODULE_SHIPPING_SAPARCELPLUS_ECONOPARCEL_MAX_WEIGHT', '1000', 'The weight at which EconoParcel becomes ParcelPlus.', '6', '5', now())");
      tep_db_query("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added) values ('Insurance cost minimum fee.', 'MODULE_SHIPPING_SAPARCELPLUS_INSURANCE_MINIMUM', '2.00', 'The minimum allowed insurance cost.', '6', '5', now())");
      tep_db_query("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added) values ('Maximum insured value.', 'MODULE_SHIPPING_SAPARCELPLUS_INSURANCE_MAXIMUM', '5000.00', 'The maximum insurable value.', '6', '5', now())");
      tep_db_query("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added) values ('Insurance Rate for ECONOPARCEL parcels.', 'MODULE_SHIPPING_SAPARCELPLUS_ECONOPARCEL_INSURANCE_RATE', '2', 'The insurance cost as a percentage of the parcel value (2 = 2%). To turn off insurance, enter 0.', '6', '5', now())");
      tep_db_query("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added) values ('Insurance Rate for PARCELPLUS parcels.', 'MODULE_SHIPPING_SAPARCELPLUS_PARCELPLUS_INSURANCE_RATE', '2', 'The insurance cost as a percentage of the parcel value (2 = 2%). To turn off insurance, enter 0.', '6', '5', now())");
      tep_db_query("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added) values ('EconoParcel base shipping rate', 'MODULE_SHIPPING_SAPARCELPLUS_ECONOPARCEL_BASE_RATE', '12.60', 'EconoParcel base rate. Example: 12.60', '6', '5', now())");
      tep_db_query("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added) values ('EconoParcel unit shipping rate per kilo after the first (set to 0)', 'MODULE_SHIPPING_SAPARCELPLUS_ECONOPARCEL_UNIT_RATE', '0', 'EconoParcel unit rate (should stay 0). Example: 0', '6', '5', now())");
      tep_db_query("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added) values ('ParcelPlus base shipping rate', 'MODULE_SHIPPING_SAPARCELPLUS_PARCELPLUS_BASE_RATE', '23.65', 'ParcelPlus base rate (fee for first kilo). Example: 23.65', '6', '5', now())");
      tep_db_query("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added) values ('ParcelPlus unit shipping rate per kilo after the first', 'MODULE_SHIPPING_SAPARCELPLUS_PARCELPLUS_UNIT_RATE', '3.05', 'ParcelPlus unit rate (for each kilo after the first one). Example: 3.05', '6', '5', now())");
      tep_db_query("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added) values ('Handling Fee', 'MODULE_SHIPPING_SAPARCELPLUS_HANDLING_FEE', '0', 'Handling Fee for SA domestic parcels', '6', '1', now())");
    }

    function remove() { 
    /**************************************************************************
    *                                Remove                                   *
    * Purpose: Deletes all the configuration keys
    **************************************************************************/
      tep_db_query("delete from " . TABLE_CONFIGURATION . " where configuration_key in ('" . implode("', '", $this->keys()) . "')");
    }

    function keys() {
    /**************************************************************************
    *                                Remove                                   *
    * Purpose: Returns all the keys used by this module.
    **************************************************************************/
      $keys = array('MODULE_SHIPPING_SAPARCELPLUS_STATUS', 
                    'MODULE_SHIPPING_SAPARCELPLUS_SORT_ORDER', 
                    'MODULE_SHIPPING_SAPARCELPLUS_TAX_CLASS', 
                    'MODULE_SHIPPING_SAPARCELPLUS_MAX_WEIGHT',
                    'MODULE_SHIPPING_SAPARCELPLUS_HANDLING_FEE',
                    'MODULE_SHIPPING_SAPARCELPLUS_INSURANCE_MAXIMUM',
                    'MODULE_SHIPPING_SAPARCELPLUS_INSURANCE_MINIMUM',
                    'MODULE_SHIPPING_SAPARCELPLUS_ECONOPARCEL_MAX_WEIGHT',
                    'MODULE_SHIPPING_SAPARCELPLUS_ECONOPARCEL_INSURANCE_RATE',
                    'MODULE_SHIPPING_SAPARCELPLUS_PARCELPLUS_INSURANCE_RATE',
                    'MODULE_SHIPPING_SAPARCELPLUS_ECONOPARCEL_BASE_RATE',
                    'MODULE_SHIPPING_SAPARCELPLUS_ECONOPARCEL_UNIT_RATE',
                    'MODULE_SHIPPING_SAPARCELPLUS_PARCELPLUS_BASE_RATE',
                    'MODULE_SHIPPING_SAPARCELPLUS_PARCELPLUS_UNIT_RATE'
                    );

      return $keys;
    }
  }
?>
